package com.openroom.ui.component.skin;

import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;

import org.apache.pivot.wtk.Component;
import org.apache.pivot.wtk.ComponentMouseButtonListener;
import org.apache.pivot.wtk.ComponentMouseListener;
import org.apache.pivot.wtk.Mouse.Button;
import org.apache.pivot.wtk.media.Image;

import com.openroom.event.ApplicationEvent;
import com.openroom.event.EventHandler;
import com.openroom.event.EventManager;
import com.openroom.event.EventType;
import com.openroom.model.ModelLocator;
import com.openroom.model.ModelLocator.ModeFlag.ImageViewMode;
import com.openroom.ui.component.BorderImage;
import com.openroom.ui.component.BorderImageSkin;
import com.openroom.ui.component.ZoomablePreviewImage;

public class ZoomablePreviewImageSkin extends BorderImageSkin {

    public static int RECT_HEIGHT = 50;

    public static int RECT_WIDTH = 50;

    private int previewWidth = 0;
    private int previewHeight = 0;

    public ZoomablePreviewImageSkin() {
    }

    private boolean isDragging = false;

    int rectX = 0;
    int rectY = 0;
    int mouseOffsetX = 0;
    int mouseOffsetY = 0;

    private float xRatio;

    private float yRatio;

    @Override
    public void install(Component component) {
        super.install(component);
        getComponent().getComponentMouseListeners().add(
                new ComponentMouseListener() {
                    @Override
                    public boolean mouseMove(Component component, int x, int y) {
                        if (isDragging) {
                            boolean contains = new Rectangle(imageX - 2,
                                    imageY - 2,
                                    ((int) (imageSize.width * scaleX)) + 4,
                                    ((int) (imageSize.height * scaleY)) + 4)
                                    .contains(new Point(x - mouseOffsetX, y
                                            - mouseOffsetY));
                            if (contains) {
                                rectX = x - mouseOffsetX;
                                rectY = y - mouseOffsetY;
                            }
                            getComponent().repaint();
                        }
                        return false;
                    }

                    @Override
                    public void mouseOver(Component component) {

                    }

                    @Override
                    public void mouseOut(Component component) {

                    }
                });
        getComponent().getComponentMouseButtonListeners().add(
                new ComponentMouseButtonListener() {

                    @Override
                    public boolean mouseDown(Component component,
                            Button button, int x, int y) {

                        if (x < rectX + RECT_WIDTH && y < RECT_HEIGHT + rectY
                                && x > rectX && y > rectY) {
                            isDragging = true;
                            mouseOffsetX = x - rectX;
                            mouseOffsetY = y - rectY;
                        }
                        return false;
                    }

                    @Override
                    public boolean mouseUp(Component component, Button button,
                            int x, int y) {
                        isDragging = false;
                        rectX = x - RECT_WIDTH / 2 - imageX;
                        rectY = y - RECT_HEIGHT / 2 - imageY;
                        int xoffset = x - imageX;
                        int yoffset = y - imageY;
                        int newX = (int) (xoffset * xRatio);
                        int newY = (int) (yoffset * yRatio);
                        ((ZoomablePreviewImage) getComponent()).moveTo(newX,
                                newY);
                        getComponent().repaint();
                        return false;
                    }

                    @Override
                    public boolean mouseClick(Component component,
                            Button button, int x, int y, int count) {
                        return false;
                    }

                });
        EventManager.getInstance().listenToEventType(
                EventType.VIEW_MODE_CHANGED, new EventHandler() {
                    @Override
                    public void handle(ApplicationEvent event) {
                        getComponent().repaint();
                    }
                });
    }

    @Override
    public void layout() {
        super.layout();
        rectX = imageX;
        rectY = imageY;
        Image image = ((BorderImage) getComponent()).getImage();
        int ow = ModelLocator.getInstance().getCurrentImageWidth();
        int oh = ModelLocator.getInstance().getCurrentImageHeight();
        if (getWidth() != 0 && getHeight() != 0 && ow != 0) {
            xRatio = ow / (image.getWidth() * scaleX);
            yRatio = oh / (image.getHeight() * scaleY);
            RECT_WIDTH = (int) ((previewWidth * image.getWidth() * scaleX) / ow);
            RECT_HEIGHT = (int) ((previewHeight * image.getHeight() * scaleY) / oh);
        } else {
            // System.out.println("ZoomablePreviewImageSkin.enclosing_method()");
        }
    }

    @Override
    public void paint(Graphics2D graphics) {
        super.paint(graphics);
        if (ModelLocator.getInstance().getCurrentImageMode() == ImageViewMode.FULL_VIEW) {
            try {
                graphics.drawRect(imageX + rectX, imageY + rectY, RECT_WIDTH,
                        RECT_HEIGHT);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public int getPreviewWidth() {
        return previewWidth;
    }

    public void setPreviewWidth(int previewWidth) {
        this.previewWidth = previewWidth;
    }

    public int getPreviewHeight() {
        return previewHeight;
    }

    public void setPreviewHeight(int previewHeight) {
        this.previewHeight = previewHeight;
    }

}
